package zgrjb.snbq.teach_platform.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import zgrjb.snbq.teach_platform.dto.model.User;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类 - 简化版本
 * 支持生成和解析JWT token，以及cookie操作
 */
@Slf4j
public class JwtUtil {

    /**
     * 密钥
     */
    private static final String SECRET = "xht20241017_super_secret_key_for_jwt_token_generation";

    /**
     * 过期时间，7天
     */
    private static final long EXPIRE = 1000 * 60 * 60 * 24 * 7;

    /**
     * Token前缀
     */
    private static final String TOKEN_PREFIX = "xht-teach-admin";

    /**
     * 主题
     */
    private static final String SUBJECT = "xht-teach-admin";

    /**
     * Cookie名称
     */
    private static final String COOKIE_NAME = "token";

    /**
     * 生成JWT Token - 简化版本
     * @param user 用户信息
     * @return JWT token
     */
    public static String geneAttendeeJsonWebTokne(User user) {
        if (user == null || user.getId() == null || user.getName() == null || user.getPhone() == null) {
            log.warn("用户信息不完整，无法生成token");
            return null;
        }

        try {
            Map<String, Object> claims = new HashMap<>();
            claims.put("id", user.getId());
            claims.put("name", user.getName());
            claims.put("phone", user.getPhone());
            claims.put("email", user.getEmail());
            claims.put("type", user.getType());
            claims.put("headImg", user.getHeadImg());

            String token = Jwts.builder()
                    .setSubject(SUBJECT)
                    .setClaims(claims)
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                    .signWith(SignatureAlgorithm.HS256, SECRET)
                    .compact();

            log.info("JWT token生成成功，用户: {}", user.getName());
            return TOKEN_PREFIX + token;
        } catch (Exception e) {
            log.error("生成JWT token失败: {}", e.getMessage(), e);
            return "temporary_token_" + user.getId() + "_" + System.currentTimeMillis();
        }
    }

    /**
     * 校验token - 简化版本
     * @param token JWT token
     * @return Claims
     */
    public static Claims checkJWT(String token) {
        try {
            if (token == null || !token.startsWith(TOKEN_PREFIX)) {
                return null;
            }

            // 去掉前缀
            String actualToken = token.replace(TOKEN_PREFIX, "");
            
            final Claims claims = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(actualToken)
                    .getBody();
            
            return claims;
        } catch (Exception e) {
            log.warn("JWT token解析失败: {}", e.getMessage());
            return null;
        }
    }

    /**
     * 校验用户JWT token (兼容旧版本方法名)
     * @param token JWT token
     * @return Claims
     */
    public static Claims checkAttendeeJWT(String token) {
        return checkJWT(token);
    }

    /**
     * 从请求中获取token
     * 优先从cookie中获取，其次从Authorization header中获取
     * @param request HTTP请求
     * @return JWT token
     */
    public static String getTokenFromRequest(HttpServletRequest request) {
        // 首先尝试从cookie中获取
        String tokenFromCookie = getTokenFromCookie(request);
        if (tokenFromCookie != null) {
            return tokenFromCookie;
        }

        // 其次从Authorization header中获取
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }

        return null;
    }

    /**
     * 从cookie中获取token
     * @param request HTTP请求
     * @return JWT token
     */
    public static String getTokenFromCookie(HttpServletRequest request) {
        if (request.getCookies() == null) {
            return null;
        }

        for (Cookie cookie : request.getCookies()) {
            if (COOKIE_NAME.equals(cookie.getName())) {
                return cookie.getValue();
            }
        }
        return null;
    }

    /**
     * 将token设置到cookie中
     * @param response HTTP响应
     * @param token JWT token
     */
    public static void setTokenToCookie(HttpServletResponse response, String token) {
        Cookie cookie = new Cookie(COOKIE_NAME, token);
        cookie.setPath("/");
        cookie.setMaxAge((int) (EXPIRE / 1000)); // 转换为秒
        cookie.setHttpOnly(true); // 防止XSS攻击
        cookie.setSecure(false); // 开发环境设置为false，生产环境应该设置为true
        response.addCookie(cookie);
    }

    /**
     * 清除cookie中的token
     * @param response HTTP响应
     */
    public static void clearTokenFromCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie(COOKIE_NAME, null);
        cookie.setPath("/");
        cookie.setMaxAge(0);
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    /**
     * 从Claims中解析用户信息
     * @param claims JWT Claims
     * @return User对象
     */
    public static User parseUserFromClaims(Claims claims) {
        if (claims == null) {
            log.warn("Claims为空");
            return null;
        }

        try {
            log.info("开始解析JWT Claims: {}", claims);
            
            User user = new User();
            
            // 处理id字段
            Object idObj = claims.get("id");
            log.info("解析id字段: {}, 类型: {}", idObj, idObj != null ? idObj.getClass().getSimpleName() : "null");
            if (idObj != null) {
                Long id = null;
                if (idObj instanceof Integer) {
                    id = ((Integer) idObj).longValue();
                } else if (idObj instanceof Long) {
                    id = (Long) idObj;
                } else {
                    id = Long.valueOf(idObj.toString());
                }
                user.setId(id);
                log.info("设置用户ID: {}", id);
            }
            
            // 处理其他字段
            String name = claims.get("name", String.class);
            String phone = claims.get("phone", String.class);
            String email = claims.get("email", String.class);
            String type = claims.get("type", String.class);
            String headImg = claims.get("headImg", String.class);
            
            log.info("解析其他字段 - name: {}, phone: {}, email: {}, type: {}, headImg: {}", 
                    name, phone, email, type, headImg);
            
            user.setName(name);
            user.setPhone(phone);
            user.setEmail(email);
            user.setType(type);
            user.setHeadImg(headImg);
            
            log.info("用户信息解析成功: id={}, name={}, type={}", user.getId(), user.getName(), user.getType());
            return user;
        } catch (Exception e) {
            log.error("解析用户信息失败: {}", e.getMessage(), e);
            return null;
        }
    }
}
